//! 数据中心

#![no_std]
#![feature(const_fn_fn_ptr_basics)]
extern crate alloc;

pub mod event;
pub mod request;

use spin::Once;
use unmp::id::*;
use unmp::Connection;
use unmp_center_core::{CmdType, Data};
use unmp_protocol_etp::{Addr, Config, Socket};

const MY_ETP_PORT: u8 = 0x64;
pub const CENTER_ID: Id = UniqueId::new(0, 1).id();
const CENTER_ETP_PORT: u8 = 0x64;
const CENTER_ETP: Addr = Addr::new(Connection::new(CENTER_ID), CENTER_ETP_PORT);
static SOCKET: Once<Socket> = Once::new();

pub fn init() {
    if let None = SOCKET.get() {
        unmp_protocol_etp::init();
        let socket = Socket::new(MY_ETP_PORT, Config { retry: 3 });
        if let Ok(mut socket) = socket {
            socket.bind(CENTER_ETP);
            SOCKET.call_once(|| socket);
            task_stream::spawn(async {
                let rep = SOCKET.get().unwrap().recv().await;
                if let Ok(rep) = rep {
                    let data = Data::parse(&rep.body);
                    match data.cmd().cmd_type() {
                        CmdType::Request => {}
                        CmdType::Respose | CmdType::Unknow => request::recv(data).await,
                        CmdType::Notice => event::recv(&data),
                    }
                }
            });
        }
    }
}
pub(crate) async fn send(buf: &[u8]) -> Result<(), ()> {
    SOCKET.get().unwrap().send(buf).await
}
